<template>
  <div class="canvas-container">
    <div class="buttons-container">
      <span class="button-label">飞行</span>
      <div class="separator"></div>
      <button class="buttons_fly" @click="handleTakeoffOrLand">
        <img class="image_button"
             :src="flightStatus ? 'src/assets/images/bt_land.svg' : 'src/assets/images/bt_takeoff.svg'"
             :alt="flightStatus ? '降落' : '起飞'"/>
        <span>{{ flightStatus ? '降落' : '起飞' }}</span>
      </button>
      <button class="buttons_fly" @click="handleReturn" :disabled="!flightStatus">
        <img class="image_button" src="../assets/images/bt_return.svg" alt="返航"/>
        <span>返航</span>
      </button>
      <span class="button-label">轨迹</span>
      <div class="separator"></div>
      <button class="buttons_fly" @click="setDrawingModeLine">
        <img class="image_button" src="../assets/images/bt_line.svg" alt="直线"/>
        <span>直线</span>
      </button>
      <button class="buttons_fly" @click="setDrawingModeRectangle">
        <img class="image_button" src="../assets/images/bt_rectangle.svg" alt="矩形"/>
        <span>矩形</span>
      </button>
      <button class="buttons_fly" @click="setDrawingModeCircle">
        <img class="image_button" src="../assets/images/bt_cycle.svg" alt="圆形"/>
        <span>圆形</span>
      </button>
      <button class="buttons_fly" @click="handleSend" :disabled="!flightStatus || isExecTask">
        <img class="image_button" :src="isExecTask ? 'src/assets/images/bt_wait.svg' : 'src/assets/images/bt_send.svg'"
             :alt="isExecTask ? '等待' : '发送'"/>
        <span>{{ isExecTask ? '等待' : '发送' }}</span>
      </button>
      <button class="buttons_fly" @click="clearTrackList">
        <img class="image_button" src="../assets/images/bt_clear.svg" alt="清除"/>
        <span>清除</span>
      </button>
    </div>
    <canvas ref="canvas"></canvas>
    <div class="flight-indicator">
      <div class="indicator attitude-indicator">
        <Attitude :size="130" :roll="roll" :pitch="pitch"/>
      </div>
      <div class="indicator heading-indicator">
        <Heading :size="130" :heading="yaw"/>
      </div>
      <div class="info-panel">
        <div class="info-title">
          {{ customModeText }} {{ systemStatusText }}
        </div>
        <div class="separator"></div>
        <div class="info-item">
          <span class="info-label">高度(m):</span>
          <span class="info-value">{{ altitude }}</span>
        </div>
        <div class="info-item">
          <span class="info-label">速度(m/s):</span>
          <span class="info-value">{{ speed }}</span>
        </div>
        <div class="info-item">
          <span class="info-label">飞行时间:</span>
          <span class="info-value">{{ flightTime }}</span>
        </div>
      </div>
      <div class="task-panel">
        <div class="task-title">任务中心
          <button @click="fetchFlyTasks" style="float: right;background-color: transparent;border: none; display: flex; justify-content: center; align-items: center; z-index: 20">
            <img
                src="../assets/images/bt_refresh.svg"
                style="width: 15px;height: 15px"
            />
          </button>
        </div>
        <div class="separator"></div>
        <div class="scroll">
          <div class="list">
            <div v-for="flyTaskData in flyTaskList" :key="flyTaskData.trackId" class="list-item">
              <img
                  :src="flyTaskData.creatClient === 'PC' ? pcIcon : mobileIcon"
                  class="task-icon"
              />
              <div class="task-info">
                <div class="task-row">
                  {{ flyTaskData.flyTaskName }}
                </div>
                <div class="task-row">
                  <span class="task-value">{{ flyTaskData.flyStartDate.replace('T', '  ') }}</span>
                </div>
              </div>
              <button class="task-btn">查看</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="scale-indicator"><p>{{ scaleText }}</p></div>

  <div v-if="showContextMenu" :style="{ top: `${contextMenuPosition.y}px`, left: `${contextMenuPosition.x}px` }"
       class="context-menu">
    <ul>
      <li v-if="!isExecTask" @click="handleContextMenuAction('setSpeed')">设置速度</li>
      <li v-if="flightStatus && !isExecTask" @click="handleContextMenuAction('goToPoint')">飞行至该点</li>
      <li @click="handleContextMenuAction('setMode')">设置模式</li>
    </ul>
  </div>

  <!-- 速度设置弹窗 -->
  <div v-if="showSpeedDialog" class="dialog-overlay" @click="closeSpeedDialog">
    <div class="dialog" @click.stop>
      <h3>设置速度</h3>
      <input type="range" v-model="speedValue" min="0.01" max="3" step="0.05"/>
      <p>当前速度: {{ speedValue }}m/s</p>
      <div class="button-container">
        <button @click="confirmSpeed">确认</button>
        <button @click="closeSpeedDialog">取消</button>
      </div>
    </div>
  </div>

  <!-- 模式设置弹窗 -->
  <div v-if="showModeDialog" class="dialog-overlay" @click="closeModeDialog">
    <div class="dialog" @click.stop>
      <h3>设置模式</h3>
      <select v-model="selectedMode">
        <option value="手动Manual">手动Manual</option>
        <option value="自稳Stabilized">自稳Stabilized</option>
        <option value="特技Acro">特技Acro</option>
        <option value="定高Altitude">定高Altitude</option>
        <option value="板外Offboard">板外Offboard</option>
        <option value="定点Position">定点Position</option>
        <option value="任务Mission">任务Mission</option>
        <option value="返航return">返航return</option>
      </select>
      <div class="button-container">
        <button @click="confirmMode">确认</button>
        <button @click="closeModeDialog">取消</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import {onMounted, onUnmounted, ref, watch} from 'vue';
import {fabric} from 'fabric';
import LineData from "@/model/LineData.js";
import RectangleData from "@/model/RectangleData.js";
import CircleData from "@/model/CircleData.js";
import airplaneImage from '../assets/images/img_plane.svg';
import homeImage from '../assets/images/img_home.svg';
import {Attitude, Heading} from 'vue-flight-indicators';
import axios from "axios";
import pcIcon from '../assets/images/PC.svg';
import mobileIcon from '../assets/images/mobile.svg';

let isFirst = ref(true);//是否第一次加载
let isFirstData = ref(true);//是否第一次加载数据
const canvas = ref(null);
let canvasConst = null;//画布常量
let gridSpacing = 50; // 网格间距
let isDragging = false;
let lastPosX = 0;
let lastPosY = 0;
const current_x = ref(0);//绘制x
const current_y = ref(0);//绘制y
const local_x = ref(0);//飞机当前点x
const local_y = ref(0);//飞机当前点y
const pre_x = ref(0);//上次绘制的x
const pre_y = ref(0);//上次绘制的y
const home_x = ref(0);//home的x
const home_y = ref(0);//home的y
const scale = ref(1); // 比例尺
const scaleText = ref("Scale: 100%"); // 比例尺文本
let isDrawing = false;
const drawingMode = ref(null); // Drawing mode
const trackDataList = ref([]); // 存储所有图形绘制历史的数组
let yaw = ref(0);//航向角
let roll = ref(0);
let pitch = ref(0);
let flightTime = ref('00:00:00');
let timer = null;
let speed = ref('0.0');
let altitude = ref('0.0');
let flightStatus = ref(false);//是否起飞的状态
let isExecTask = ref(false)//是否处于自定义规划
const showContextMenu = ref(false);//右键菜单是否显示
const contextMenuPosition = ref({x: 0, y: 0});//菜单的相对位置
const showSpeedDialog = ref(false);
const showModeDialog = ref(false);
const speedValue = ref(0.2);
const customModeText = ref('未知');//模式信息
const systemStatusText = ref('未解锁');//系统状态
const clickToPoint = ref(null);//前往点
const selectedMode = ref('定点模式');
const flyTaskList = ref([]);
// 统一的图形数据结构
const TrackData = {
  type: '', // 'line', 'rectangle', 'circle'
  data: null, // 具体的图形数据
};
const ws = new WebSocket("ws://localhost:9090/ws/messages");

const handleContextMenuAction = async (action) => {
  showContextMenu.value = false;
  if (action === 'setSpeed') {
    showSpeedDialog.value = true; // 显示速度设置弹窗
  } else if (action === 'goToPoint') {
    try {
      isExecTask.value = true;
      const deltaX = clickToPoint.value.y - local_x.value;
      const deltaY = clickToPoint.value.x - local_y.value;
      let distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY) / 100.0;

      const response = await axios.post('http://localhost:9090/drone/flyLine', {
        startX: local_x.value / 100.0,
        startY: local_y.value / 100.0,
        endX: -clickToPoint.value.y / 100.0,
        endY: clickToPoint.value.x / 100.0,
        flightAltitude: 3,
        duration_s: distance / speedValue.value
      });
      current_x.value = clickToPoint.value.x;
      current_y.value = clickToPoint.value.y;
      // 请求完成后执行的逻辑
      console.log('Flight to point request successful:', response.data);

    } catch (error) {
      // 处理请求失败的逻辑
      console.error('Flight to point request failed:', error);
    } finally {
      isExecTask.value = false;
    }
    console.log(`Parameters: -${clickToPoint.value.y}, ${clickToPoint.value.x}, ${local_y.value}, -${local_x.value}`);
  }
  else if (action === 'setMode'){
    showModeDialog.value = true; // 显示模式设置弹窗
  }
};

const handleContextMenu = (opt) => {
  contextMenuPosition.value = {x: opt.e.clientX, y: opt.e.clientY};
  clickToPoint.value = canvasConst.getPointer(opt.e);
  showContextMenu.value = true;
};

const handleClickOutside = () => {
  showContextMenu.value = false;
};
const closeSpeedDialog = () => {
  showSpeedDialog.value = false;
};

const banContextMenu = (event) => {
  event.preventDefault();
};

const confirmSpeed = () => {
  console.log(`设置的速度: ${speedValue.value}`);
  closeSpeedDialog();
};
const closeModeDialog = () => {
  showModeDialog.value = false;
};

const confirmMode = (mode) => {
  console.log(`Selected mode: ${selectedMode.value}`);
  closeModeDialog();
};
const onMessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.yaw !== undefined) {
    yaw.value = message.yaw / 3.14 * 180;
  }
  if (message.roll !== undefined) {
    roll.value = -message.roll / 3.14 * 180;
  }
  if (message.pitch !== undefined) {
    pitch.value = message.pitch / 3.14 * 180;
  }
  if (message.x !== undefined) {
    local_x.value = message.x * 100;
  }
  if (message.y !== undefined) {
    local_y.value = message.y * 100;
  }
  if (message.z !== undefined) {
    altitude.value = message.z;
  }
  if (message.customModeText !== undefined) {
    customModeText.value = message.customModeText;
  }
  if (message.systemStatusText !== undefined) {
    systemStatusText.value = message.systemStatusText;
  }
  if (isFirstData.value) {
    pre_x.value = message.x * 100;
    pre_y.value = message.y * 100;
    current_x.value = message.y * 100;
    current_y.value = -message.x * 100;
    isFirstData.value = false;
  }
  if (message.groundSpeed !== undefined) {
    speed.value = message.groundSpeed;
  }
  drawSmoothCurve(local_x.value, local_y.value);
};

const addAirplaneImage = () => {
  fabric.Image.fromURL(airplaneImage, (img) => {
    img.set({
      left: local_y.value,
      top: -local_x.value,
      originX: 'center',
      originY: 'center',
      scaleX: 0.15,
      scaleY: 0.15,
      selectable: false
    });
    canvasConst.add(img);

    // Update position and rotation based on heading
    img.on('added', () => {
      updateAirplanePositionAndRotation(img);
    });
  });
};

const addHomePositionImage = () => {
  fabric.Image.fromURL(homeImage, (img) => {
    img.set({
      left: home_y.value,
      top: -home_x.value,
      originX: 'center',
      originY: 'center',
      scaleX: 0.15,
      scaleY: 0.15,
      selectable: false
    });
    canvasConst.add(img);

    // Update position and rotation based on heading
    // img.on('added', () => {
    //   updateAirplanePositionAndRotation(img);
    // });
  });
};

watch(yaw, () => {
  const img = canvasConst.getObjects().find(obj => obj.type === 'image');
  if (img) {
    updateAirplanePositionAndRotation(img);
  }
});

watch(systemStatusText, () => {
  if(systemStatusText.value === '解锁'){
    flightStatus.value = true;
  }
  else if(systemStatusText.value === '未解锁'){
    flightStatus.value = false;
  }
});

watch(flightStatus, () => {
    if (flightStatus.value) {
      startTimer();
    } else {
      resetTimer();
    }
});
function startTimer() {
  let hours = 0, minutes = 0, seconds = 0;
  timer = setInterval(() => {
    seconds++;
    if (seconds === 60) {
      seconds = 0;
      minutes++;
    }
    if (minutes === 60) {
      minutes = 0;
      hours++;
    }
    flightTime.value = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
  }, 1000);
}

function resetTimer() {
  clearInterval(timer);
  flightTime.value = '00:00:00';
}
const updateAirplanePositionAndRotation = (img) => {
  img.set({
    left: local_y.value,
    top: -local_x.value,
    angle: yaw.value, // Rotate based on heading
  });
  canvasConst.renderAll();
};


// setInterval(() => {
//   yaw.value = yaw.value + 0.9;
//   roll.value = roll.value + 0.1;
//   pitch.value = pitch.value + 0.1;
//   // drawPoint(heading.value,heading.value)
// }, 35);

const handleTakeoffOrLand = () => {
  if (!flightStatus.value) {
    axios.post('http://localhost:9090/drone/setAutoTakeoffMode')
        .then(response => {
          console.log('自动起飞请求成功', response);
          // 处理成功响应的逻辑
        })
        .catch(error => {
          console.error('自动起飞请求失败', error);
          // 处理请求失败的逻辑
        });
    flightStatus.value = true;
    addHomePositionImage();
  } else {
    isExecTask.value = false;
    axios.post('http://localhost:9090/drone/sendLandCommand')
        .then(response => {
          console.log('降落请求成功', response);
          // 处理成功响应的逻辑
        })
        .catch(error => {
          console.error('降落请求失败', error);
          // 处理请求失败的逻辑
        });
    flightStatus.value = false;
  }
};

const handleReturn = () => {
  isExecTask.value = false;
  axios.post('http://localhost:9090/drone/return')
      .then(response => {
        console.log('自动返航请求成功', response);
        // 处理成功响应的逻辑
      })
      .catch(error => {
        console.error('自动返航请求失败', error);
        // 处理请求失败的逻辑
      });
};
const handleSend = async () => {
  isExecTask.value = true;
  console.log(JSON.stringify(trackDataList.value, null, 2));
  for (const [index, trackData] of trackDataList.value.entries()) {
    if (!isExecTask.value) {
      break;
    }

    async function handleFlyLine() {
      try {
        const deltaX = trackData.data.endX - trackData.data.startX;
        const deltaY = trackData.data.endY - trackData.data.startY;
        let distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY) / 100.0
        const response = await axios.post('http://localhost:9090/drone/flyLine', {
          startX: trackData.data.startX / 100.0,
          startY: trackData.data.startY / 100.0,
          endX: trackData.data.endX / 100.0,
          endY: trackData.data.endY / 100.0,
          flightAltitude: 0.5,
          duration_s: distance / speedValue.value
        });
        // 处理成功响应的逻辑
      } catch (error) {
        // 处理请求失败的逻辑
      }
    }

    async function handleFlyRectangle() {
      try {
        const width = Math.abs(trackData.data.endX - trackData.data.startX);
        const height = Math.abs(trackData.data.endY - trackData.data.startY);
        let distance = 2 * (width + height) / 100.0;
        const response = await axios.post('http://localhost:9090/drone/flyRectangleByP2P', {
          endX: trackData.data.endX / 100.0,
          endY: trackData.data.endY / 100.0,
          current_x: trackData.data.startX / 100.0,
          current_y: trackData.data.startY / 100.0,
          flightAltitude: 0.5,
          clockwise: true,
          cycle_s: distance / speedValue.value
        });
        // 处理成功响应的逻辑
      } catch (error) {
        // 处理请求失败的逻辑
      }
    }

    async function handleFltCircle() {
      try {
        let distance = 2 * Math.PI * trackData.data.radius / 100.0;
        const response = await axios.post('http://localhost:9090/drone/flyCircle', {
          radius: trackData.data.radius / 100.0,
          clockwise: true,
          current_x: trackData.data.startX / 100.0,
          current_y: trackData.data.startY / 100.0,
          flightAltitude: 0.5,
          cycle_s: distance / speedValue.value,
          isup: trackData.data.isup

        });
        // 处理成功响应的逻辑
      } catch (error) {
        // 处理请求失败的逻辑
      }
    }

    switch (trackData.type) {
      case 'line':
        await handleFlyLine();
        console.log(`Line ${index + 1}: Start(${trackData.data.startX}, ${trackData.data.startY}), End(${trackData.data.endX}, ${trackData.data.endY})`);
        break;
      case 'rectangle':
        await handleFlyRectangle();
        console.log(`Rectangle ${index + 1}: Left(${trackData.data.startX}), Top(${trackData.data.startY}), Width(${trackData.data.endX}), Height(${trackData.data.endY})`);
        break;
      case 'circle':
        await handleFltCircle();
        console.log(`Circle ${index + 1}: Center(${trackData.data.startX}, ${trackData.data.startY}), Radius(${trackData.data.radius}), isup(${trackData.data.isup})`);
        break;
      default:
        console.log(`Unknown shape type for item ${index + 1}`);
    }
  }
  isExecTask.value = false;
};

const clearTrackList = () => {
  if (trackDataList.value.length > 0) {
    current_x.value = trackDataList.value[0].data.startY
    current_y.value = -trackDataList.value[0].data.startX
  }
  console.log(current_x.value, current_y.value)
  trackDataList.value = []; // 清空轨迹数组
  clearCanvas(); // 清空画布图形
  addAirplaneImage();
};

const clearCanvas = () => {
  canvasConst.clear(); // 清空画布内容
  drawAxes(); // 重新绘制坐标轴和网格线
};

const onClick1 = () => {
  trackDataList.value.forEach((trackData, index) => {
    switch (trackData.type) {
      case 'line':
        console.log(`Line ${index + 1}: Start(${trackData.data.startX}, ${trackData.data.startY}), End(${trackData.data.endX}, ${trackData.data.endY})`);
        break;
      case 'rectangle':
        console.log(`Rectangle ${index + 1}: Left(${trackData.data.left}), Top(${trackData.data.top}), Width(${trackData.data.width}), Height(${trackData.data.height})`);
        break;
      case 'circle':
        console.log(`Circle ${index + 1}: Center(${trackData.data.startX}, ${trackData.data.startY}), Radius(${trackData.data.radius})`);
        break;
      default:
        console.log(`Unknown shape type for item ${index + 1}`);
    }
  });
};

const addDrawingEvents = () => {
  // 鼠标滚轮缩放
  canvasConst.on('mouse:wheel', (opt) => {
    const delta = opt.e.deltaY;
    let zoom = canvasConst.getZoom();

    zoom *= 0.999 ** delta;
    if (zoom > 20) zoom = 20;
    if (zoom < 0.01) zoom = 0.01;
    canvasConst.zoomToPoint({x: opt.e.offsetX, y: opt.e.offsetY}, zoom);
    updateScaleText(zoom);
    opt.e.preventDefault();
    opt.e.stopPropagation();
  });

  // 监听对象缩放事件，用于更新比例尺文本
  canvasConst.on('object:scaling', (opt) => {
    const zoom = canvasConst.getZoom();
    updateScaleText(zoom);
  });

  // 拖动视图
  canvasConst.on('mouse:down', (opt) => {
    const evt = opt.e;
    if (evt.altKey === true) {
      isDragging = true;
      lastPosX = evt.clientX;
      lastPosY = evt.clientY;
    } else if (drawingMode.value === 'line' && isDrawing) {
      if (opt.e.button === 0) {
        finishDrawingLine(opt);
      } else if (opt.e.button === 2) {
        cancelDrawingLine();
      }
    } else if (drawingMode.value === 'circle' && isDrawing) {
      if (opt.e.button === 0) {
        finishDrawingCircle(opt);
      } else if (opt.e.button === 2) {
        cancelDrawingCircle();
      }
    } else if (drawingMode.value === 'rectangle' && isDrawing) {
      if (opt.e.button === 0) {
        finishDrawingRectangle(opt);
      } else if (opt.e.button === 2) {
        cancelDrawingRectangle();
      }
    } else if (opt.e.button === 2) {
      handleContextMenu(opt);
    } else if (opt.e.button === 0) {
      handleClickOutside();
    }
  });

  canvasConst.on('mouse:move', (opt) => {
    if (isDragging) {
      const e = opt.e;
      const vpt = canvasConst.viewportTransform;
      vpt[4] += e.clientX - lastPosX;
      vpt[5] += e.clientY - lastPosY;
      canvasConst.requestRenderAll();
      lastPosX = e.clientX;
      lastPosY = e.clientY;
    } else if (drawingMode.value === 'line' && isDrawing) {
      drawLine(opt);
    } else if (drawingMode.value === 'circle' && isDrawing) {
      drawCircle(opt);
    } else if (drawingMode.value === 'rectangle' && isDrawing) {
      drawRectangle(opt);
    }
  });

  canvasConst.on('mouse:up', (opt) => {
    if (isDragging) {
      isDragging = false;
    }
  });
};

const drawAxes = () => {
  const width = canvasConst.getWidth();
  const height = canvasConst.getHeight();

  // 创建X轴
  const xAxis = new fabric.Line([-width * 10, 0, width * 10, 0], {
    stroke: 'black',
    strokeWidth: 1,
    selectable: false,
  });

  // 创建Y轴
  const yAxis = new fabric.Line([0, -height * 10, 0, height * 10], {
    stroke: 'black',
    strokeWidth: 1,
    selectable: false,
  });

  canvasConst.add(xAxis);
  canvasConst.add(yAxis);

  // 添加网格线
  const gridLineOptions = {
    stroke: '#ccc',
    strokeWidth: 1,
    selectable: false,
  };

  // X轴方向的网格线
  for (let i = 0; i <= width * 10; i += gridSpacing) {
    if (i !== 0) {
      const line_l = new fabric.Line([i, -height * 10, i, height * 10], gridLineOptions);
      const line_r = new fabric.Line([-i, -height * 10, -i, height * 10], gridLineOptions);
      canvasConst.add(line_l);
      canvasConst.add(line_r);
    }
  }

  // Y轴方向的网格线
  for (let j = 0; j <= height * 10; j += gridSpacing) {
    if (j !== 0) {
      const line_t = new fabric.Line([-width * 10, j, width * 10, j], gridLineOptions);
      const line_b = new fabric.Line([-width * 10, -j, width * 10, -j], gridLineOptions);
      canvasConst.add(line_t);
      canvasConst.add(line_b);
    }
  }

  canvasConst.renderAll();
};

const updateScaleText = (zoom) => {
  const scalePercentage = Math.round(zoom * 100);
  scale.value = zoom;
  scaleText.value = `Scale: ${scalePercentage}%`;
};

const setDrawingModeLine = () => {
  drawingMode.value = 'line';
  startDrawingLine();
};

const startDrawingLine = () => {
  isDrawing = true;
  const points = [current_x.value, current_y.value, current_x.value, current_y.value];
  const line = new fabric.Line(points, {
    strokeWidth: 2,
    fill: 'black',
    stroke: 'black',
    originX: 'center',
    originY: 'center',
    selectable: false
  });
  canvasConst.add(line);
  canvasConst._currentLine = line;
};

const drawLine = (opt) => {
  const pointer = canvasConst.getPointer(opt.e);
  const line = canvasConst._currentLine;
  line.set({x2: pointer.x, y2: pointer.y});
  canvasConst.renderAll();
};

const finishDrawingLine = (opt) => {
  isDrawing = false;
  const pointer = canvasConst.getPointer(opt.e);
  const lineData = {
    ...LineData,
    startX: -current_y.value,
    startY: current_x.value,
    endX: -pointer.y,
    endY: pointer.x,
  };
  const shapeData = {
    type: 'line',
    data: lineData,
  };
  current_x.value = pointer.x;
  current_y.value = pointer.y;
  trackDataList.value.push(shapeData);
  canvasConst._currentLine = null;
};

const cancelDrawingLine = () => {
  isDrawing = false;
  canvasConst.remove(canvasConst._currentLine);
  canvasConst._currentLine = null;
};

const setDrawingModeCircle = () => {
  drawingMode.value = 'circle';
  startDrawingCircle();
};

const startDrawingCircle = () => {
  isDrawing = true;
  const circleRadius = 10; // 圆的半径
  const startPoint = {
    x: current_x.value,
    y: current_y.value - circleRadius // 将起点调整到圆的圆弧上
  };
  const circle = new fabric.Circle({
    left: startPoint.x - circleRadius,
    top: startPoint.y - circleRadius,
    originX: 'left',
    originY: 'top',
    radius: circleRadius,
    strokeWidth: 2,
    fill: 'rgba(0,0,0,0)',
    stroke: 'black',
    selectable: false
  });
  canvasConst.add(circle);
  canvasConst._currentCircle = circle;
};

const drawCircle = (opt) => {
  const pointer = canvasConst.getPointer(opt.e);
  const startPoint = {
    x: current_x.value,
    y: current_y.value,
  };
  const radius = Math.sqrt(Math.pow(pointer.x - startPoint.x, 2) + Math.pow(pointer.y - startPoint.y, 2));
  const circle = canvasConst._currentCircle;
  if (pointer.y < startPoint.y) {
    circle.set({
      radius: radius,
      left: startPoint.x - radius,
      top: startPoint.y - 2 * radius,
      originX: 'left',
      originY: 'top'
    });
  } else {
    circle.set({
      radius: radius,
      left: startPoint.x - radius,
      top: startPoint.y,
      originX: 'left',
      originY: 'top'
    });
  }
  canvasConst.renderAll();
};

const finishDrawingCircle = (opt) => {
  isDrawing = false;
  const pointer = canvasConst.getPointer(opt.e);
  const startPoint = {
    x: current_x.value,
    y: current_y.value,
  };
  const radius = Math.sqrt(Math.pow(pointer.x - startPoint.x, 2) + Math.pow(pointer.y - startPoint.y, 2));
  let circleData;
  if (pointer.y < startPoint.y) {
    circleData = {
      ...CircleData,
      startX: -current_y.value,
      startY: current_x.value,
      radius: radius,
      isup: true
    };
  } else {
    circleData = {
      ...CircleData,
      startX: -current_y.value,
      startY: current_x.value,
      radius: radius,
      isup: false
    };
  }

  const shapeData = {
    type: 'circle',
    data: circleData,
  };
  trackDataList.value.push(shapeData);
  canvasConst._currentCircle.set({radius});
  canvasConst._currentCircle = null;
};

const cancelDrawingCircle = () => {
  isDrawing = false;
  canvasConst.remove(canvasConst._currentCircle);
  canvasConst._currentCircle = null;
};

const setOriginToCenter = () => {
  const width = canvasConst.getWidth();
  const height = canvasConst.getHeight();
  canvasConst.viewportTransform[4] = width / 2;
  canvasConst.viewportTransform[5] = height / 2;
};

const setDrawingModeRectangle = () => {
  drawingMode.value = 'rectangle';
  startDrawingRectangle();
};

const startDrawingRectangle = () => {
  isDrawing = true;
  const points = [current_x.value, current_y.value, current_x.value, current_y.value];
  const rect = new fabric.Rect({
    left: current_x.value,
    top: current_y.value,
    width: 0,
    height: 0,
    stroke: 'black',
    strokeWidth: 2,
    fill: 'rgba(0,0,0,0)',
    selectable: false
  });
  canvasConst.add(rect);
  canvasConst._currentRectangle = rect;
};

const drawRectangle = (opt) => {
  const pointer = canvasConst.getPointer(opt.e);
  const rect = canvasConst._currentRectangle;

  const left = Math.min(current_x.value, pointer.x);
  const top = Math.min(current_y.value, pointer.y);
  const width = Math.abs(pointer.x - current_x.value);
  const height = Math.abs(pointer.y - current_y.value);

  rect.set({left, top, width, height});
  canvasConst.renderAll();
};

const finishDrawingRectangle = (opt) => {
  isDrawing = false;
  const pointer = canvasConst.getPointer(opt.e);
  const rectData = {
    ...RectangleData,
    startX: -current_y.value,
    startY: current_x.value,
    endX: -pointer.y,
    endY: pointer.x,
  };
  const shapeData = {
    type: 'rectangle',
    data: rectData,
  };
  trackDataList.value.push(shapeData);
  canvasConst._currentRectangle = null;
};

const cancelDrawingRectangle = () => {
  isDrawing = false;
  canvasConst.remove(canvasConst._currentRectangle);
  canvasConst._currentRectangle = null;
};

const drawPoint = (x, y) => {
  let temp = x.valueOf();
  x = y.valueOf();
  y = -temp;

  const point = new fabric.Circle({
    left: x - 3,
    top: y - 3,
    radius: 3,
    fill: 'green',
    selectable: false, // Makes the point non-interactive
    evented: false, // Ensures the point does not trigger events
  });
  canvasConst.add(point);
  canvasConst.renderAll();
};

const drawSmoothCurve = (x, y) => {
  // Convert and adjust the coordrawSmoothCurvedinates
  let temp = x.valueOf();
  x = y.valueOf();
  y = -temp;

  // Create a path string for a quadratic Bezier curve
  const pathString = `M ${pre_y.value} ${-pre_x.value} Q ${(pre_y.value + x) / 2} ${(-pre_x.value + y) / 2} ${x} ${y}`;
  // Create a path object
  const path = new fabric.Path(pathString, {
    stroke: 'blue',
    strokeWidth: 2,
    fill: 'transparent',
    selectable: false, // Makes the path non-interactive
    evented: false, // Ensures the path does not trigger events
  });
  pre_x.value = -y;
  pre_y.value = x;

  // Add the path to the canvas and render
  canvasConst.add(path);
  canvasConst.renderAll();
};

onMounted(() => {
  document.addEventListener('contextmenu', banContextMenu);
  ws.onmessage = onMessage;
  ws.onopen = () => console.log("WebSocket connection established.");
  ws.onclose = () => console.log("WebSocket connection closed.");
  ws.onerror = (error) => console.error("WebSocket error:", error);
  console.log('114141')
  fetchFlyTasks();
  canvas.value = new fabric.Canvas(canvas.value, {
    fireRightClick: true,
    stopContextMenu: true,
  });
  canvasConst = canvas.value;
  addDrawingEvents();
  addAirplaneImage();
  // 设置画布大小为全屏
  const resizeCanvas = () => {
    canvasConst.setWidth(window.innerWidth);
    canvasConst.setHeight(window.innerHeight);
    if (isFirst.value) {
      setOriginToCenter();
      drawAxes(); // 绘制坐标轴和网格线
      isFirst.value = false;
    }
    canvasConst.renderAll();
  };

  resizeCanvas();
  window.addEventListener('resize', resizeCanvas);

  // 清除事件监听器
  onUnmounted(() => {
    window.removeEventListener('resize', resizeCanvas);
    document.removeEventListener('contextmenu', banContextMenu);
  });
});

const fetchFlyTasks = async () => {
  const response = await axios.get('http://localhost:9090/flytask/getAll', {});
  console.log(response.data.data)
  flyTaskList.value = response.data.data;
};

onUnmounted(() => {
  ws.close();
});
</script>

<style scoped>
html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden; /* 确保没有滚动条 */
}

.canvas-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative; /* 确保比例尺相对于canvas-container定位 */
}

canvas {
  border: none;
  display: block; /* 移除默认的inline样式 */
}

.scale-indicator {
  position: absolute;
  bottom: 10px;
  right: 10px;
  background-color: rgba(255, 255, 255, 0.8);
  padding: 5px 10px;
  border-radius: 5px;
  font-size: 14px;
  pointer-events: none; /* 确保比例尺不影响鼠标事件 */
}

.buttons-container {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  flex-direction: column;
  text-align: center; /* 确保容器内的文字居中 */
  background: #d0cece;
  z-index: 10;
}

.buttons-container button {
  margin-bottom: 10px;
}

.flight-indicator {
  position: absolute;
  width: 260px;
  height: 800px;
  top: 10px;
  right: 10px;
  display: flex;
  flex-direction: row;
  align-items: flex-end;
  z-index: 10;
}

.indicator {
  margin-bottom: 10px;
}

.attitude-indicator {
  position: absolute;
  /* Optional: Adjust styles for Attitude indicator */
  width: 130px; /* Adjust width if needed */
  height: 130px; /* Adjust height if needed */
  top: 0px;
  right: 120px;
}

.heading-indicator {
  /* Optional: Adjust styles for Heading indicator */
  width: 130px; /* Adjust width if needed */
  height: 130px; /* Adjust height if needed */
}

.buttons_fly {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: none;
  cursor: pointer;
  border: none;
  justify-content: center; /* 元素内容在纵向居中 */
  text-align: center; /* 文字居中 */
}

.image_button {
  width: 50px; /* 调整图片宽度 */
  height: 50px; /* 保持图片比例 */
}

.buttons_fly span {
  margin-top: 5px; /* 调整文字与图片之间的间距 */
  font-size: 14px; /* 调整文字大小 */
  color: #333; /* 调整文字颜色 */
}

.button-label {
  margin-bottom: 5px;
  font-size: 16px;
  color: #333;
}

.separator {
  width: 100%;
  height: 1px;
  background-color: #000000; /* 分隔符颜色 */
  margin: 4px 0; /* 分隔符上下间距 */
}

.info-panel {
  position: absolute;
  /* Optional: Adjust styles for Attitude indicator */
  width: 260px; /* Adjust width if needed */
  height: 200px; /* Adjust height if needed */
  top: 140px;
  right: 0px;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid #333;
  border-radius: 10px;
  padding: 5px;
  text-align: center;
}

.task-panel {
  position: absolute;
  /* Optional: Adjust styles for Attitude indicator */
  width: 260px; /* Adjust width if needed */
  height: 320px; /* Adjust height if needed */
  top: 360px;
  right: 0px;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid #333;
  border-radius: 10px;
  padding: 5px;
  text-align: center;
}

.info-item {
}

.info-label {
  font-size: 10pt;
  color: #333;
  display: block; /* 确保标签独占一行 */
}

.info-value {
  font-weight: bold;
  font-size: 15pt;
  color: #333;
  display: block; /* 确保值独占一行 */
}

.buttons_fly:disabled {
  opacity: 0.2; /* 按钮禁用时透明度变为 50% */
  pointer-events: none; /* 禁止点击事件 */
}

.context-menu {
  position: absolute;
  background-color: white;
  border: 1px solid #ccc;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  z-index: 1000;
}

.context-menu ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.context-menu li {
  padding: 8px 12px;
  cursor: pointer;
}

.context-menu li:hover {
  background-color: #eee;
}

.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.dialog {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  width: 300px;
  text-align: center;
}

.dialog h3 {
  margin-top: 0;
  color: #333;
  font-size: 1.5em;
}

.dialog input[type="range"] {
  width: 100%;
  margin: 20px 0;
}

.dialog p {
  margin: 10px 0;
  color: #555;
  font-size: 1.2em;
}

.button-container {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.list-item{
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #ffffff;
  border-radius: 10px;
  padding: 10px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin-bottom: 10px;
}

.task-icon {
  width: 50px;
  height: 50px;
  width: 20%;
}

.task-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 80%;
}

.task-row {
  align-items: center;
  width: 100%;
}

.task-value {
  font-size: 16px;
}

.task-btn {
  width: 20%;
  flex: 0 0 auto;
  padding: 10px 0px;
  font-size: 16px;
  color: #fff;
  background-color: #007bff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.task-btn:hover {
  background-color: #0056b3;
}

.scroll {
  height: 280px; /* 固定高度，可以根据需要调整 */
  overflow-y: auto; /* 超出高度时显示纵向滚动条 */
  padding: 10px;
  scrollbar-width: none; /* 适用于 Firefox */
  -ms-overflow-style: none; /* 适用于 Internet Explorer 和 Edge */
}

.scroll::-webkit-scrollbar {
  display: none; /* 适用于 Chrome, Safari 和 Opera */
}
.task-title{

}
</style>